/**
 * OPay Inc.
 * Copyright (c) 2016-2022 All Rights Reserved.
 */
package cc.dd.marketing.core;/**
 * @author sufeng.dong
 * @version $Id: LoadBeanToMap.java, v 0.1 2022-09-13 7:07 PM sufeng.dong Exp $$
 */

import cc.dd.marketing.api.constant.ActivityTypeEnum;
import cc.dd.marketing.api.constant.FunctionCodeEnum;
import cc.dd.marketing.core.annotation.ActivityTypeMapper;
import cc.dd.marketing.core.annotation.CouponTemplateMapper;
import cc.dd.marketing.core.annotation.FunctionMapper;
import cc.dd.marketing.core.annotation.RewardMapper;
import cc.dd.marketing.core.base.RequestParser;
import cc.dd.marketing.core.constant.CouponTemplateEnum;
import cc.dd.marketing.common.Constants;
import cc.dd.marketing.core.base.BusinessHandler;
import cc.dd.marketing.core.base.ResponseParser;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Auther: dongsufeng
 * @Date: 2022/9/13 19:07
 * @Description:
 */
@Component
public class LoadBeanToMap implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Class[] types = new Class[]{BusinessHandler.class, RequestParser.class, ResponseParser.class};
        for (Class type : types) {
            Map map = applicationContext.getBeansOfType(type);
            for (Object bean : map.values()) {
                FunctionMapper fMap = bean.getClass().getAnnotation(FunctionMapper.class);
                if (fMap == null) {
                    throw new RuntimeException(bean.getClass() + " has not Annotation @FunctionMapper");
                }
                if (fMap.value().length == 0) {
                    throw new RuntimeException(bean.getClass() + " @FunctionMapper is empty");
                }
                String[] businessList = getBusinessList(bean);
                for (FunctionCodeEnum function : fMap.value()) {
                    CommonFactory.container.put(type, function, businessList, bean);
                }
            }
        }
    }

    /**
     * 获取注解内容
     *
     * @param obj
     * @return
     */
    private String[] getBusinessList(Object obj) {
        List<String> list = new ArrayList<>();
        ActivityTypeMapper activityMap = obj.getClass().getAnnotation(ActivityTypeMapper.class);
        if (activityMap != null) {
            ActivityTypeEnum[] values = activityMap.value();
            for (ActivityTypeEnum value : values) {
                list.add(value.getCode());
            }
            return list.stream().toArray(String[]::new);
        }
        RewardMapper rewardMapper = obj.getClass().getAnnotation(RewardMapper.class);
        if (rewardMapper != null) {
            list.add(String.format(Constants.AWARD_BEAN_PREFIX, rewardMapper.value().getCode()));
            return list.stream().toArray(String[]::new);
        }
        CouponTemplateMapper couponTemplateMapper = obj.getClass().getAnnotation(CouponTemplateMapper.class);
        if (couponTemplateMapper != null) {
            CouponTemplateEnum[] values = couponTemplateMapper.value();
            for (CouponTemplateEnum value : values) {
                list.add(value.getCode());
            }
            return list.stream().toArray(String[]::new);
        }
        return null;
    }
}
